﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TcpEchoServer
{
    public class Program
    {
        private const int BUFSIZE = 32;

        private static void Main(string[] args)
        {           
            int servPort = 7;
            TcpListener listener = null;

            try
            {
                // Create a TCPListener to accept client connections
                listener = new TcpListener(IPAddress.Any, servPort);
                listener.Start();
            }
            catch (SocketException se)
            {
                Console.WriteLine(se.ErrorCode + ": " + se.Message);
                Environment.Exit(se.ErrorCode);
            }

            var rcvBuffer = new byte[BUFSIZE]; // Receive buffer
            int bytesRcvd; // Received byte count

            for (;;)
            {
                // Run forever, accepting and servicing connections

                TcpClient client = null;
                NetworkStream netStream = null;

                try
                {
                    client = listener.AcceptTcpClient(); // Get client connection
                    netStream = client.GetStream();
                    Console.Write("Handling client - ");

                    // Receive until client closes connection, indicated by 0 return value
                    int totalBytesEchoed = 0;
                    while ((bytesRcvd = netStream.Read(rcvBuffer, totalBytesEchoed, rcvBuffer.Length - totalBytesEchoed)) > 0)
                    {                     
                        netStream.Write(rcvBuffer, totalBytesEchoed, bytesRcvd);
                        totalBytesEchoed += bytesRcvd;                                 
                    }
                    Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);

                    // Close the stream and socket. We are done with this client!
                    netStream.Close();
                    client.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    netStream.Close();
                }
            }
        }
    }
}